#include "tcpSrv.h"

/*
 * static function
*/
typedef struct _FdSet
{
    int total;
    int fdArray[FD_SETSIZE];
}FdSet;
static void FdSet_INSERT(FdSet *set, int fd)
{
    set->fdArray[set->total] = fd; 
    set->total++;    
}
static int  FdSet_GETMAX(FdSet *set){
    int max_fd=-1;
    int i=0;
    for(i=0;i<set->total;i++){
        if(max_fd < set->fdArray[i])
            max_fd = set->fdArray[i];
    }
    return max_fd+1;
}

static void FdSet_REMOVE(FdSet * set,int fd){
    FdSet tmp;
    tmp.total = 0;
    int i = 0;
    for (i = 0;i < set->total; i++ ){
        if ( fd != set->fdArray[i] ){
            tmp.fdArray[tmp.total] = set->fdArray[i];
            tmp.total++;
        }
    }
    memset(set->fdArray,0,sizeof(int)*FD_SETSIZE);
    set->total = tmp.total;
    for ( i = 0; i < set->total; i++){
        set->fdArray[i] = tmp.fdArray[i];
    }
}



/*
 * TCP function
*/
int creatTcpSocket( int port){
    int fd;
    if (0 > (fd = socket(AF_INET, SOCK_STREAM, 0))){
        PRTLOG("create socket errno:%d   %s",errno,strerror(errno));      
        PRTLOG("socket error:%d",errno);
        return -1;
    }
    
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int sock_opt = 1;
    // if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt,sizeof(sock_opt))) == -1) {
    //     PRTLOG("setsockopt error:%d",errno);
    //     return -1;
    // }
    if(0 > bind(fd, (const struct sockaddr *)&addr, sizeof(struct sockaddr))){
        PRTLOG("bind errno:%d   %s",errno,strerror(errno));        
        return -1;
    }
    if (0 > listen(fd,MAXCONNECT_NUM)){
        PRTLOG("listen errno:%d   %s",errno,strerror(errno));       
        return -1;
    }
    return fd;
}
void selectLoop(int fd){
    struct timeval timeout;
    fd_set read_set;
    int i=0;
    FdSet read_FdSet;
    FD_SET(fd,&read_set);
    FdSet_INSERT(&read_FdSet,fd);
    int ret=-1;
    while(20190705){
        FD_ZERO(&read_set);
        for(i=0;i<read_FdSet.total;i++){
            FD_SET(read_FdSet.fdArray[i],&read_set);
        }
        timeout.tv_sec=2;
        timeout.tv_usec=0;
        ret = select(FdSet_GETMAX(&read_FdSet),&read_set,NULL,NULL,&timeout);
        if(ret <0){/*Error*/
            PRTLOG("select errno:%d   %s",errno,strerror(errno));       
            continue;
        }else if(ret==0){/*TimeOut*/
            continue;
        }else{/*Get ready readable fd*/
             for(i=0;i<read_FdSet.total;i++){
                 if(FD_ISSET(read_FdSet.fdArray[i],&read_set)){
                     struct sockaddr client_addr;
                     int len = sizeof(struct sockaddr);
                     int clifd=-1;
                     clifd=accept(read_FdSet.fdArray[i],&client_addr,&len);
                     if(clifd<0){
                         PRTLOG("accept client socket errno:%d   %s",errno,strerror(errno));      
                     }else{
                        char rcvData[GLB_LEN_4096]={'\0'};
                        int recvLen=0;
                        recvLen = recv(clifd,rcvData,sizeof(char)*GLB_LEN_4096,0);
                        if(recvLen >0){
                            if(rtsp_judge(rcvData)){
                                rtsp_hanling(rcvData,clifd);
                            }
                        }
                        close(clifd);
                     }
                 }
             }
        } 
    }
    for(i=0;i<read_FdSet.total;i++){
        fclose(read_FdSet.fdArray[i]);
    }
}




